/* eslint-disable no-unused-vars */

import VectorLayer from 'ol/layer/Vector';
import { Circle as CircleStyle, Fill, Stroke, Style, Text, Icon } from 'ol/style';
import VectorSource from 'ol/source/Vector';
import GeoJSON from 'ol/format/GeoJSON';
import { Point, LineString, Polygon, Circle } from 'ol/geom';
import Feature from 'ol/Feature';
import Overlay from 'ol/Overlay';
import Draw from 'ol/interaction/Draw'
import { getArea, getLength } from 'ol/sphere';
import { unByKey } from 'ol/Observable';
import WKT from 'ol/format/WKT';
// js
import { chartConfig } from "@/page/chart/options";
import { transformLineForPoint, transformLonlatToNow, transformNowToLonlat, CalculationAngle, getCenterPoint, pointLonToXy, getRadius, removeDomById, AlarmInfoTips } from "./util"
import { getStore, setStore, removeStore } from "@/utils/store"
import { LayerZIndex } from "../options"
import { findStrength, ToDigital } from "@/utils/chart"

// 绘制时的样式
const measureStyle = () => {
  return new Style({
    fill: new Fill({
      color: 'rgba(255, 255, 255, 0.2)'
    }),
    stroke: new Stroke({
      color: 'rgba(0, 0, 0, 0.5)',
      lineDash: [10, 10],
      width: 2
    }),
    image: new CircleStyle({
      radius: 3,
      stroke: new Stroke({
        color: 'rgba(0, 0, 0, 0.7)'
      }),
      fill: new Fill({
        color: 'rgba(255, 255, 255, 0.2)'
      })
    })
  })
}

// 绘制图形样式
const drawStyle = () => {
  return new Style({
    fill: new Fill({
      color: 'rgba(100, 205, 142, 0.5)'
    }),
    stroke: new Stroke({
      color: 'rgba(0, 0, 0, 0.5)',
      width: 2
    }),
    image: new CircleStyle({
      radius: 3,
      stroke: new Stroke({
        color: 'rgba(0, 0, 0, 0.7)'
      }),
      fill: new Fill({
        color: 'rgba(255, 255, 255, 0.2)'
      })
    })
  })
}

// 测绘图形中点的样式
function drawStyleFn(feature) {
  let styleList = [drawStyle()]
  const coordinatesType = feature.getGeometry().getType();
  if (coordinatesType === "Circle") return styleList
  const Coordinates = feature.getGeometry().getCoordinates();
  let list = coordinatesType === "Polygon" ? Coordinates[0] : Coordinates;
  const colors = ["#88FF88", "#FFFFFF", "#D53645"];
  var fn = (row, index = 1) => {
    styleList.push(
      new Style({
        zIndex: 10,
        image: new CircleStyle({
          radius: 3.5,
          fill: new Fill({
            color: colors[index],
          }),
          stroke: new Stroke({
            color: "#333333",
            width: 1.5,
          }),
        }),
        geometry: new Point(row),
      })
    );
  };
  if (coordinatesType === "Polygon") {
    list = list.slice(0, list.length - 1);
  }
  for (let item of list.slice(1, list.length - 1)) {
    fn(item, 1);
  }
  fn(list[0], 0);
  fn(list[list.length - 1], 2);
  return styleList;
}

// 共享信息样式
const shareStyle = (type) => {
  let baseStyles = {
    fill: {
      color: 'rgba(39, 112, 112, 0.5)'
    },
    stroke: {
      color: 'rgba(0, 0, 0, 0.5)',
      width: 2,
    },
    image: {
      radius: 3,
      stroke: new Stroke({
        color: 'rgba(0, 0, 0, 0.7)'
      }),
      fill: new Fill({
        color: 'rgba(255, 255, 255, 0.2)'
      })
    },
    // text: {
    //   text: row.title,
    //   font: 'bold 12px sans-serif',
    //   fill: new Fill({
    //     color: '#061F5D',
    //   }),
    //   offsetX: 0,
    //   offsetY: 20,
    // }
  }
  let styles = {}
  if (type === "Point") {
    styles = {
      fill: new Fill(baseStyles.fill),
      text: new Text(baseStyles.text)
    }
  } else if (type === "LineString") {
    baseStyles.stroke.lineDash = [3, 4]
    baseStyles.stroke.color = "#094ba6"
    styles = {
      fill: new Fill(baseStyles.fill),
      stroke: new Stroke(baseStyles.stroke),
      image: new CircleStyle(baseStyles.image),
      text: new Text(baseStyles.text)
    }
  } else {
    styles = {
      fill: new Fill(baseStyles.fill),
      stroke: new Stroke(baseStyles.stroke),
      image: new CircleStyle(baseStyles.image),
      text: new Text(baseStyles.text)
    }
  }
  return new Style(styles)
}

function shareStyleForPoint(row) {
  return new Style({
    zIndex: 10,
    image: new Icon({
      src: '/img/chart/flag.png',
    }),
    geometry: new Point(row),
  })
}

function shareStyleForLineString(row) {
  return new Style({
    zIndex: 10,
    image: new CircleStyle({
      radius: 2,
      fill: new Fill({
        color: "#88FF88",
      }),
      stroke: new Stroke({
        color: "#333333",
        width: 1.5,
      }),
    }),
    geometry: new Point(row),
  })
}

// 共享信息样式
function shareStyleFn(feature) {
  const detail = feature.values_
  const coordinatesType = feature.getGeometry().getType();
  let styleList = [shareStyle(coordinatesType, detail)]
  const Coordinates = feature.getGeometry().getCoordinates();
  if (coordinatesType === "Point") {
    styleList.push(shareStyleForPoint(Coordinates))
  } else if (coordinatesType === "LineString") {
    for (let item of Coordinates) {
      styleList.push(shareStyleForLineString(item))
    }
  }
  // const Coordinates = feature.getGeometry().getCoordinates();
  // let list = coordinatesType === "Polygon" ? Coordinates[0] : Coordinates;
  // if (coordinatesType === "Polygon") {
  //   list = list.slice(0, list.length - 1);
  // }
  return styleList;
}

// 航海通告样式
function noticeStyleForPoint(row) {
  return new Style({
    zIndex: 10,
    image: new Icon({
      src: '/img/chart/notice.png',
    }),
    geometry: new Point(row),
  })
}

function noticeStyleForLineString(row) {
  return new Style({
    zIndex: 10,
    image: new CircleStyle({
      radius: 2,
      fill: new Fill({
        color: "#88FF88",
      }),
      stroke: new Stroke({
        color: "#333333",
        width: 1.5,
      }),
    }),
    geometry: new Point(row),
  })
}

function noticeStyleFn(feature) {
  const detail = feature.values_
  const coordinatesType = feature.getGeometry().getType();
  let styleList = [shareStyle(coordinatesType, detail)]
  const Coordinates = feature.getGeometry().getCoordinates();
  if (coordinatesType === "Point") {
    styleList.push(noticeStyleForPoint(Coordinates))
  } else if (coordinatesType === "LineString") {
    for (let item of Coordinates) {
      styleList.push(noticeStyleForLineString(item))
    }
  }
  return styleList;
}

// 八大区域的初始化颜色
const areaColorList = [
  "213, 120, 170",
  "152, 255, 188",
  "180, 233, 120",
  "22, 180, 255",
  "25, 255, 255",
  "36, 120, 200",
  "180, 26, 180",
  "36, 255, 170"
]

// 八大区的样式设置
const areaStyleFn = (feature) => {
  let list = []
  list.push(
    new Style({
      fill: new Fill({
        color: `rgba(${areaColorList[feature.values_.index]}, 0.2)`,
      }),
      stroke: new Stroke({
        color: `rgba(${areaColorList[feature.values_.index]}, 1)`,
        width: 1.5
      }),
    })
  )
  const lonAndLat = feature.values_.pointList.map(m => transformLonlatToNow([m.lon, m.lat]))
  const centerPoint = getCenterPoint(lonAndLat)
  list.push(
    new Style({
      zIndex: 10,
      text: new Text({
        text: feature.values_.areaName,
        font: '30px sans-serif',
        fill: new Fill({
          color: "rgba(0, 0, 0, 0.5)",
        }),
      }),
      geometry: new Point(centerPoint),
    })
  );
  return list
}

// 电子围栏初始化样式
var alarmStyle = [
  new Style({
    fill: new Fill({
      color: "rgba(213, 120, 170, 0.2)"
    }),
    stroke: new Stroke({
      color: "rgba(255, 1, 1, 1)",
      width: 1.5
    }),
  })
]

// 电子围栏线之间点的样式
const alarmStyleFn = (feature) => {
  const Coordinates = feature.getGeometry().getCoordinates();
  let list = Coordinates[0];
  list = list.slice(0, list.length - 1);
  var fn = (row) => {
    alarmStyle.push(
      new Style({
        zIndex: 10,
        image: new CircleStyle({
          radius: 3.5,
          fill: new Fill({
            // color: "#D53645",
            color: "#d2d2d2"
          }),
          stroke: new Stroke({
            color: "#f00",
            width: 0.8,
          }),
        }),
        geometry: new Point(row),
      })
    );
  };
  for (let item of list) {
    fn(item);
  }
  return alarmStyle;
}

var nMile = 1852

// 长度对象
const formatLengthForUtil = (line) => {
  var length = getLength(line, {
    radius: 6378137,
    projection: chartConfig.EPSGCode
  });
  // var output;
  // if (length > 100) {
  //   output = (Math.round(length / 1000 * 100) / 100) +
  //     ' ' + 'km';
  // } else {
  //   output = (Math.round(length * 100) / 100) +
  //     ' ' + 'm';
  // }
  const nm = (length / nMile).toFixed(3)
  return {
    length: nm,
    output: nm + "nm",
  };
}

// 长度
const formatLength = (line) => {
  var length = getLength(line, {
    radius: 6378137,
    projection: chartConfig.EPSGCode
  });
  // var output;
  // if (length > 100) {
  //   output = (Math.round(length / 1000 * 100) / 100) +
  //     ' ' + 'km';
  // } else {
  //   output = (Math.round(length * 100) / 100) +
  //     ' ' + 'm';
  // }
  const nm = (length / nMile).toFixed(3) + "nm"
  return nm;
}

// 面积
const formatArea = (polygon) => {
  var area = getArea(polygon, {
    radius: 6378137,
    projection: chartConfig.EPSGCode
  });
  var output;
  if (area > 10000) {
    output = (Math.round(area / 1000000 * 100) / 100) +
      ' ' + 'km<sup>2</sup>';
  } else {
    output = (Math.round(area * 100) / 100) +
      ' ' + 'm<sup>2</sup>';
  }
  return output;
}

function getCoordinate(list) {
  let x = 0, y = 0;
  let length = list.length
  length = length === 2 ? 2 : length - 1
  for (let index = 0; index < length; ++index) {
    x += list[index][0]
    y += list[index][1]
  }
  return [
    x / length,
    y / length
  ]
}

export default {
  // 船舶尾迹
  drawShipWake: (map, list) => {
    var styles = [
      new Style({
        stroke: new Stroke({
          color: '#2078F0',
          width: 2,
          lineDash: [5, 8],
        }),
      })
    ]
    var geojsonObject = {
      type: 'FeatureCollection',
      crs: {
        type: 'shipWake',
      },
      features: []
    };
    // 绘制轨迹点
    let lineList = [];
    for (let item of list) {
      const p = [parseFloat(item.lon), parseFloat(item.lat)]
      lineList.push(p)
      styles.push(new Style({
        zIndex: LayerZIndex.wave,
        // image: new CircleStyle({
        //   radius: 3,
        //   fill: new Fill({
        //     color: '#0078F0'
        //   })
        // }),
        geometry: new Point(p)
      }))
    }
    // 处理轨迹点数据
    lineList = transformLineForPoint(lineList, transformLonlatToNow)
    geojsonObject.features.push(
      {
        type: 'Feature',
        geometry: {
          type: "LineString",
          coordinates: lineList
        }
      }
    )
    var source = new VectorSource({
      features: (new GeoJSON()).readFeatures(geojsonObject)
    });
    let layerTmp = new VectorLayer({
      source: source,
      zIndex: LayerZIndex.wave,
      style: styles,
      name: "WAVE"
    });
    map.addLayer(layerTmp);
  },
  // 船舶航线
  drawShipLine: (map, data) => {
    var colorObj = {
      0: {
        color: "#17BF00",
        style: new Style({
          stroke: new Stroke({
            color: '#2770d4',
            width: 2
          }),
        }),
        startIcon: "/img/chart/shipline_start.png",
        endIcon: "/img/chart/shipline_end.png"
      },
      1: {
        color: "#7da6df",
        style: new Style({
          stroke: new Stroke({
            color: '#7da6df',
            width: 2
          }),
        }),
        startIcon: "/img/chart/shipline_start_fu.png",
        endIcon: "/img/chart/shipline_end_fu.png"
      }
    }
    var geojsonObject = {
      type: 'FeatureCollection',
      crs: {
        type: 'shipLine',
      },
      features: []
    };
    var createSignPoint = (coordinate, name, img) => {
      return new Style({
        zIndex: LayerZIndex.line,
        image: new Icon({
          src: img,
          size: [26, 50],
          // offset: [0, 13]
        }),
        text: new Text({
          text: name,
          font: 'bold 12px sans-serif',
          fill: new Fill({
            color: '#000',
          }),
          offsetX: 0,
          offsetY: 10,
        }),
        geometry: new Point(transformLonlatToNow(coordinate))
      })
    }
    let styles = []
    for (let list of [data]) {
      // 绘制航线
      let lineList = [];
      let thisStyle = [colorObj[0].style]
      for (let index in list.waypoints) {
        let item = list.waypoints[index]
        const p = [parseFloat(item.longitude), parseFloat(item.latitude)]
        lineList.push(p)
        thisStyle.push(new Style({
          zIndex: LayerZIndex.line,
          image: new CircleStyle({
            radius: 3,
            fill: new Fill({
              color: colorObj[0].color
            })
          }),
          text: new Text({
            text: (index == 0 || index == list.waypoints.length - 1) ? '' : item.pointName,
            font: 'bold 12px sans-serif',
            fill: new Fill({
              color: colorObj[0].color
            }),
            offsetX: 0,
            offsetY: 10,
            stroke: new Stroke({
              color: 'white',
              width: 1
            }),
          }),
          geometry: new Point(transformLonlatToNow(p))
        }))
      }
      thisStyle.push(createSignPoint(lineList[0], list.originPort, colorObj[0].startIcon))
      thisStyle.push(createSignPoint(lineList[lineList.length - 1], list.endPort, colorObj[0].endIcon))
      // 处理航线数据
      lineList = transformLineForPoint(lineList, transformLonlatToNow)
      geojsonObject.features.push(
        {
          type: 'Feature',
          geometry: {
            type: "LineString",
            coordinates: lineList
          }
        }
      )
      styles.push(thisStyle)
    }
    var source = new VectorSource({
      features: []
    });
    var GJson = (new GeoJSON()).readFeatures(geojsonObject)
    for (let index in GJson) {
      GJson[index].setStyle(styles[index])
      source.addFeature(GJson[index])
    }
    let layerTmp = new VectorLayer({
      source: source,
      zIndex: LayerZIndex.line,
      name: "SHIPLINE"
    });
    map.addLayer(layerTmp);
  },
  // 船舶轨迹
  drawShipTrajectory: (map, list, fn = () => { }) => {
    let layerTmp = new VectorLayer({
      source: new VectorSource({
        features: []
      }),
      zIndex: LayerZIndex.trajectory,
      name: "TRAJECTORY"
    });
    var styles = [
      new Style({
        stroke: new Stroke({
          color: '#2B579A',
          width: 2,
          // lineDash: [5, 8],
        }),
      })
    ]
    var geojsonObject = {
      type: 'FeatureCollection',
      crs: {
        type: 'shipTrajectory',
      },
      features: []
    };
    /**
     * 不同点的样式
     * 1: 起点 2: 中间点 3: 终点 4: 指向点
     */
    var stylePoint = {
      1: new CircleStyle({
        radius: 7,
        fill: new Fill({
          color: '#06C84A'
        })
      }),
      2: new CircleStyle({
        radius: 5,
        fill: new Fill({
          color: '#0078F0'
        })
      }),
      3: new CircleStyle({
        radius: 7,
        fill: new Fill({
          color: '#F70006'
        })
      }),
    }
    var arrowStyle = (c) => {
      return new Icon({
        src: '/img/chart/arrow.png',
        rotateWithView: true,
        rotation: Math.PI / (180 / c),
      })
    }
    // 计算箭头位置和角度
    function calculation(row1, row2) {
      let p1 = [parseFloat(row1.longitude), parseFloat(row1.latitude)]
      let p3 = [parseFloat(row2.longitude), parseFloat(row2.latitude)]
      let p2 = [(p1[0] + p3[0]) / 2, (p1[1] + p3[1]) / 2]
      const c = CalculationAngle([p1, p3])
      return {
        c,
        list: transformLonlatToNow(p2)
      }
    }
    // 绘制箭头
    function drawArrow(row1, row2) {
      const item = calculation(row1, row2)
      const p = [parseFloat(item.list[0]), parseFloat(item.list[1])]
      arrowList.push(p)
      styles.push(new Style({
        zIndex: LayerZIndex.trajectory,
        image: arrowStyle(item.c),
        geometry: new Point(p)
      }))
    }
    let lineList = [];
    let arrowList = []
    // 绘制轨迹点
    function drawPoint(item, index, num) {
      const p = transformLonlatToNow([parseFloat(item.longitude), parseFloat(item.latitude)])
      lineList.push(p)
      let shipFeature = new Feature({
        geometry: new Point(transformLonlatToNow([item.longitude, item.latitude])),
        name: `trajectory-${num}`,
        detail: item
      });
      shipFeature.setStyle(new Style({
        zIndex: LayerZIndex.trajectory,
        image: stylePoint[index],
      }))
      return shipFeature
    }
    layerTmp.getSource().addFeature(drawPoint(list[0], 1, 0))
    for (let index = 1; index < list.length - 1; ++index) {
      const item = list[index]
      layerTmp.getSource().addFeature(drawPoint(item, 2, index))
      drawArrow(list[index - 1], list[index])
    }
    drawArrow(list[list.length - 2], list[list.length - 1])
    layerTmp.getSource().addFeature(drawPoint(list[list.length - 1], 3, list.length))
    // 处理轨迹点数据
    geojsonObject.features.push(
      {
        type: 'Feature',
        geometry: {
          type: "LineString",
          coordinates: lineList
        },
      }
    )
    layerTmp.setStyle(styles)
    layerTmp.getSource().addFeatures(new GeoJSON().readFeatures(geojsonObject))
    map.on('pointermove', fn);
    map.addLayer(layerTmp);
  },
  // 所有船舶轨迹
  drawShipTrajectoryss: (map, list, fn = () => { }) => {
    var mapZoomIndex = parseInt(map.getView().getZoom());
    // 对应层级下显示的点位变化 - 取多少点（%）
    const showIndex = {
      1: 0,
      2: 0,
      3: 0,
      4: 0,
      5: 0,
      6: 0,
      7: 0,
      8: 0,
      9: 0,
      10: 0,
      11: 0,
      12: 0,
      13: 0,
      14: 20,
      15: 40,
      16: 60,
      17: 80,
      18: 100,
    }
    let layerTmp = new VectorLayer({
      source: new VectorSource({
        features: []
      }),
      zIndex: LayerZIndex.trajectory,
      name: "TRAJECTORY"
    });
    var styles = [
      new Style({
        stroke: new Stroke({
          color: '#2B579A',
          width: 2,
          // lineDash: [5, 8],
        }),
      })
    ]
    var geojsonObject = {
      type: 'FeatureCollection',
      crs: {
        type: 'shipTrajectory',
      },
      features: []
    };
    /**
     * 不同点的样式
     * 1: 起点 2: 中间点 3: 终点 4: 指向点
     */
    var stylePoint = {
      1: new CircleStyle({
        radius: 7,
        fill: new Fill({
          color: '#06C84A'
        })
      }),
      2: new CircleStyle({
        radius: 5,
        fill: new Fill({
          color: '#0078F0'
        })
      }),
      3: new CircleStyle({
        radius: 7,
        fill: new Fill({
          color: '#F70006'
        })
      }),
    }
    var arrowStyle = (c) => {
      return new Icon({
        src: '/img/chart/arrow.png',
        rotateWithView: true,
        rotation: Math.PI / (180 / c),
      })
    }
    // 计算箭头位置和角度
    function calculation(row1, row2) {
      let p1 = [parseFloat(row1.targetLon), parseFloat(row1.targetLat)]
      let p3 = [parseFloat(row2.targetLon), parseFloat(row2.targetLat)]
      let p2 = [(p1[0] + p3[0]) / 2, (p1[1] + p3[1]) / 2]
      const c = CalculationAngle([p1, p3])
      return {
        c,
        list: transformLonlatToNow(p2)
      }
    }
    let shipNum = 0; // 计算船舶的数量
    let pointNum = 0; // 点位的数量
    for (let key in list) {
      ++shipNum
      const line = list[key];
      pointNum += line.length;
      if (line.length < 2) {
        continue
      }
      let lineList = [];
      let arrowList = [];
      // 绘制箭头
      const drawArrow = (row1, row2) => {
        const item = calculation(row1, row2)
        const p = [parseFloat(item.list[0]), parseFloat(item.list[1])]
        arrowList.push(p)
        styles.push(new Style({
          zIndex: LayerZIndex.trajectory,
          image: arrowStyle(item.c),
          geometry: new Point(p)
        }))
      }
      // 绘制轨迹点
      const drawPoint = (item, index, num) => {
        const p = transformLonlatToNow([parseFloat(item.targetLon), parseFloat(item.targetLat)])
        lineList.push(p)
        let shipFeature = new Feature({
          geometry: new Point(transformLonlatToNow([item.targetLon, item.targetLat])),
          name: `trajectory-${num}`,
          detail: item
        });
        shipFeature.setStyle(new Style({
          zIndex: LayerZIndex.trajectory,
          image: stylePoint[index],
        }))
        return shipFeature
      }
      // 起点
      layerTmp.getSource().addFeature(drawPoint(line[0], 1, 0))
      // 中间点 - 根据当前层级获取数据
      const zIndex = showIndex[mapZoomIndex] * 0.01;
      if (zIndex !== 0) {
        const pointNum = parseInt(line.length / (line.length * zIndex));
        for (let index = 1; index < line.length - 1; index += pointNum) {
          const item = line[index]
          // layerTmp.getSource().addFeature(drawPoint(item, 2, index))
          drawArrow(line[index - pointNum], line[index])
        }
      }
      drawArrow(line[line.length - 2], line[line.length - 1])
      // 末点
      layerTmp.getSource().addFeature(drawPoint(line[line.length - 1], 3, line.length))
      // 处理轨迹点数据
      geojsonObject.features.push(
        {
          type: 'Feature',
          geometry: {
            type: "LineString",
            coordinates: lineList
          },
        }
      )
    }
    console.log("shipNum: ", shipNum)
    console.log("pointNum: ", pointNum)
    layerTmp.setStyle(styles)
    layerTmp.getSource().addFeatures(new GeoJSON().readFeatures(geojsonObject))
    map.on('pointermove', fn);
    map.addLayer(layerTmp);
  },
  // 所有船舶轨迹
  drawShipTrajectorys: (map, list, fn = () => { }) => {
    let layerTmp = new VectorLayer({
      source: new VectorSource({
        features: []
      }),
      zIndex: LayerZIndex.trajectory,
      name: "TRAJECTORY"
    });
    var styles = [
      new Style({
        stroke: new Stroke({
          color: '#2B579A',
          width: 2,
          // lineDash: [5, 8],
        }),
      })
    ]
    var geojsonObject = {
      type: 'FeatureCollection',
      crs: {
        type: 'shipTrajectory',
      },
      features: []
    };
    /**
     * 不同点的样式
     * 1: 起点 2: 中间点 3: 终点 4: 指向点
     */
    var stylePoint = {
      1: new CircleStyle({
        radius: 7,
        fill: new Fill({
          color: '#06C84A'
        })
      }),
      2: new CircleStyle({
        radius: 5,
        fill: new Fill({
          color: '#0078F0'
        })
      }),
      3: new CircleStyle({
        radius: 7,
        fill: new Fill({
          color: '#F70006'
        })
      }),
    }
    var arrowStyle = (c) => {
      return new Icon({
        src: '/img/chart/arrow.png',
        rotateWithView: true,
        rotation: Math.PI / (180 / c),
      })
    }
    // 计算箭头位置和角度
    function calculation(row1, row2) {
      let p1 = [parseFloat(row1.targetLon), parseFloat(row1.targetLat)]
      let p3 = [parseFloat(row2.targetLon), parseFloat(row2.targetLat)]
      let p2 = [(p1[0] + p3[0]) / 2, (p1[1] + p3[1]) / 2]
      const c = CalculationAngle([p1, p3])
      return {
        c,
        list: transformLonlatToNow(p2)
      }
    }
    let shipNum = 0; // 计算船舶的数量
    let pointNum = 0; // 点位的数量
    for (let key in list) {
      ++shipNum
      const line = list[key];
      pointNum += line.length;
      if (line.length < 2) {
        continue
      }
      let lineList = [];
      let arrowList = [];
      // 绘制箭头
      const drawArrow = (row1, row2) => {
        const item = calculation(row1, row2)
        const p = [parseFloat(item.list[0]), parseFloat(item.list[1])]
        arrowList.push(p)
        styles.push(new Style({
          zIndex: LayerZIndex.trajectory,
          image: arrowStyle(item.c),
          geometry: new Point(p)
        }))
      }
      // 绘制轨迹点
      const drawPoint = (item, index, num) => {
        const p = transformLonlatToNow([parseFloat(item.targetLon), parseFloat(item.targetLat)])
        lineList.push(p)
        let shipFeature = new Feature({
          geometry: new Point(transformLonlatToNow([item.targetLon, item.targetLat])),
          name: `trajectory-${num}`,
          detail: item
        });
        shipFeature.setStyle(new Style({
          zIndex: LayerZIndex.trajectory,
          image: stylePoint[index],
        }))
        return shipFeature
      }
      // 绘制线
      const drawLine = (item) => {
        const p = transformLonlatToNow([parseFloat(item.targetLon), parseFloat(item.targetLat)])
        lineList.push(p)
      }
      // 起点
      layerTmp.getSource().addFeature(drawPoint(line[0], 1, 0))
      for (let index = 1; index < line.length - 1; ++index) {
        const item = line[index]
        // layerTmp.getSource().addFeature(drawPoint(item, 2, index))
        drawLine(item)
        // drawArrow(line[index - 1], line[index])
      }
      if (line.length > 5) {
        const point1 = parseInt(line.length * 0.3)
        const point2 = parseInt(line.length * 0.6)
        drawArrow(line[point1 - 1], line[point1])
        drawArrow(line[point2 - 1], line[point2])
      } else {
        const point1 = parseInt(line.length * 0.5)
        drawArrow(line[point1 - 1], line[point1])
      }
      // 末点
      layerTmp.getSource().addFeature(drawPoint(line[line.length - 1], 3, line.length))
      // 处理轨迹点数据
      geojsonObject.features.push(
        {
          type: 'Feature',
          geometry: {
            type: "LineString",
            coordinates: lineList
          },
        }
      )
    }
    console.log("shipNum: ", shipNum)
    console.log("pointNum: ", pointNum)
    layerTmp.setStyle(styles)
    layerTmp.getSource().addFeatures(new GeoJSON().readFeatures(geojsonObject))
    map.on('pointermove', fn);
    let oldLayerTmp = map.getLayers().getArray().find(m => m.get("name") === "TRAJECTORY")
    if (oldLayerTmp) map.removeLayer(oldLayerTmp)
    map.addLayer(layerTmp);
  },
  // 测绘
  measure: (map, measureType) => {
    // 创建一个当前要绘制的对象
    var sketch;
    // 创建一个帮助提示框对象
    var helpTooltipElement;
    // 创建一个帮助提示信息对象
    var helpTooltip;
    // 创建一个测量提示框对象
    var measureTooltipElement;
    // 创建一个测量提示信息对象
    var measureTooltip;
    // 继续绘制多边形的提示信息
    var continuePolygonMsg = '双击结束绘制';
    // 继续绘制线段的提示信息
    var continueLineMsg = '双击结束绘制';
    // 创建两个提示框实例
    createMeasureTooltip();
    createHelpTooltip();

    // 绑定鼠标事件
    var pointerMoveHandler = function (evt) {
      if (evt.dragging) {
        return;
      }
      /** @type {string} */
      var helpMsg = '请点击开始绘制';

      if (sketch) {
        var geom = (sketch.getGeometry());
        if (geom instanceof Polygon) {
          helpMsg = continuePolygonMsg;
        } else if (geom instanceof LineString) {
          helpMsg = continueLineMsg;
        }
      }
      helpTooltipElement.innerHTML = helpMsg;
      helpTooltip.setPosition(evt.coordinate);
      helpTooltipElement.classList.remove('hidden');
    };

    // 添加鼠标事件
    map.on('pointermove', pointerMoveHandler);
    map.getViewport().addEventListener('mouseout', function () {
      helpTooltipElement.classList.add('hidden');
    });

    var draw;
    var source;
    var layerTmp = map.getLayers().getArray().find(m => m.get("name") === "DRAW")
    if (!layerTmp) {
      layerTmp = new VectorLayer({
        source: new VectorSource({
          features: [],
        }),
        zIndex: LayerZIndex.draw,
        name: "DRAW",
        style: drawStyleFn
      });
      map.addLayer(layerTmp)
    }
    source = layerTmp.getSource();

    // 图形样式
    draw = new Draw({
      source: source,
      type: measureType == 'area' ? 'Polygon' : 'LineString',
      style: measureStyle
    })

    function addInteraction() {
      map.addInteraction(draw);

      var listener;
      var output;
      var type;
      draw.on('drawstart',
        function (evt) {
          // set sketch
          sketch = evt.feature;

          /** @type {module:ol/coordinate~Coordinate|undefined} */
          var tooltipCoord = evt.coordinate;

          listener = sketch.getGeometry().on('change', function (evt) {
            var geom = evt.target;
            if (geom instanceof Polygon) {
              output = formatArea(geom);
              tooltipCoord = geom.getInteriorPoint().getCoordinates();
              type = "Polygon"
            } else if (geom instanceof LineString) {
              output = formatLength(geom);
              tooltipCoord = geom.getLastCoordinate();
              type = "LineString"
            }
            measureTooltipElement.innerHTML = output;
            measureTooltip.setPosition(tooltipCoord);
          });
        }, this);

      draw.on('drawend',
        function (e) {
          measureTooltipElement.className = 'draw-tooltip tooltip-static';
          measureTooltip.setOffset([0, -7]);
          sketch = null;
          measureTooltipElement = null;
          createMeasureTooltip();
          // 移除事件监听
          unByKey(listener);
          map.un('pointermove', pointerMoveHandler);
          // 获取坐标点，并存入local中
          const geometry = e.feature.getGeometry()
          let corrdinates = geometry.getCoordinates()
          if (corrdinates.length === 1) {
            corrdinates = corrdinates[0]
          }
          let list = getStore({
            name: chartConfig.chartDrawName,
          })
          const row = {
            type: type || 'Polygon',
            output: output,
            list: corrdinates
          }
          if (!list) {
            list = [row]
          } else {
            list.push(row)
          }
          setStore({
            name: chartConfig.chartDrawName,
            content: list
          })
          // 移除地图单击事件
          map.removeInteraction(draw);
          helpTooltipElement.classList.add('hidden');
        }, this);
    }

    // 将帮助提示语添加到图层中
    function createHelpTooltip() {
      if (helpTooltipElement) {
        helpTooltipElement.parentNode.removeChild(helpTooltipElement);
      }
      helpTooltipElement = document.createElement('div');
      helpTooltipElement.className = 'tooltip hidden';
      helpTooltip = new Overlay({
        element: helpTooltipElement,
        offset: [15, 0],
        positioning: 'center-left'
      });
      map.addOverlay(helpTooltip);
    }

    // 将提示语添加到图层中
    function createMeasureTooltip() {
      if (measureTooltipElement) {
        measureTooltipElement.parentNode.removeChild(measureTooltipElement);
      }
      measureTooltipElement = document.createElement('div');
      measureTooltipElement.className = 'tooltip tooltip-measure';
      measureTooltip = new Overlay({
        element: measureTooltipElement,
        offset: [0, -15],
        positioning: 'bottom-center'
      });
      map.addOverlay(measureTooltip);
    }
    // 量测调用
    addInteraction();
  },
  // 复现local storage中的历史绘制数据
  reappearance: (map, list) => {
    var geojsonObject = {
      type: 'FeatureCollection',
      crs: {
        type: 'name',
        properties: {
          name: chartConfig.EPSGCode
        }
      },
      features: []
    };
    var CirculList = []
    for (const item of list) {
      // 将坐标点放入geo中
      if (item.type === "ERBL") { // ERBL
        CirculList.push(item)
        geojsonObject.features.push(
          {
            type: 'Feature',
            geometry: {
              type: "LineString",
              coordinates: item.list
            }
          }
        )
      } else { // Polygon || LineString
        geojsonObject.features.push(
          {
            type: 'Feature',
            geometry: {
              type: item.type,
              coordinates: item.type === 'Polygon' ? [item.list] : item.list
            }
          }
        )

      }
      // 计算长度或面积，加入ele
      let measureTooltipElement = document.createElement('div');
      measureTooltipElement.className = 'draw-tooltip tooltip-measure';
      let measureTooltip = new Overlay({
        element: measureTooltipElement,
        offset: [0, 0],
        positioning: 'bottom-center'
      });
      map.addOverlay(measureTooltip);
      measureTooltipElement.innerHTML = item.output;
      if (item.type === 'Polygon') {
        measureTooltip.setPosition(getCoordinate(item.list));
      } else {
        measureTooltip.setPosition(item.list[item.list.length - 1]);
      }
    }
    var source = new VectorSource({
      features: (new GeoJSON()).readFeatures(geojsonObject)
    });
    // for (let index in CirculList) {
    //   const item = CirculList[index]
    //   var CircleBeta = new Feature({
    //     geometry: new Circle(item.list[0], parseFloat(item.util.length))
    //   })
    //   source.addFeature(CircleBeta);
    // }
    let layerTmp = map.getLayers().getArray().find(m => m.get("name") === "DRAW")
    if (!layerTmp) {
      layerTmp = new VectorLayer({
        source: new VectorSource({
          features: [],
        }),
        zIndex: LayerZIndex.draw,
        name: "DRAW",
        style: drawStyleFn
      });
      map.addLayer(layerTmp)
    }
    layerTmp.setSource(source)
  },
  // ERBL
  measureERBL: (map) => {
    // 实例
    var sketch;
    // 信息对象
    var measureTooltipElement;
    // 信息实例
    var measureTooltip;
    var pointerMoveHandler = function (evt) {
      if (evt.dragging) {
        return;
      }
    };
    // 创建实例
    createMeasureTooltip();

    // 添加鼠标事件
    map.on('pointermove', pointerMoveHandler);

    var CircleDraw;
    var lineDraw;
    var source;
    var layerTmp = map.getLayers().getArray().find(m => m.get("name") === "DRAW")
    if (!layerTmp) {
      layerTmp = new VectorLayer({
        source: new VectorSource({
          features: [],
        }),
        zIndex: LayerZIndex.draw,
        name: "DRAW",
        style: drawStyle
      });
      map.addLayer(layerTmp)
    }
    source = layerTmp.getSource();

    // 图形样式
    CircleDraw = new Draw({
      source: source,
      type: "Circle",
      style: measureStyle
    })
    lineDraw = new Draw({
      source: source,
      type: "LineString",
      style: measureStyle
    })

    function addInteraction() {
      var msg = "";
      var util = {};
      var point = [];
      map.addInteraction(CircleDraw);
      map.addInteraction(lineDraw);

      var listener;
      lineDraw.on('drawstart',
        function (evt) {
          // set sketch
          sketch = evt.feature;
          let corrdinates;
          var tooltipCoord = evt.coordinate;

          /** @type {module:ol/coordinate~Coordinate|undefined} */

          listener = sketch.getGeometry().on('change', function (evt) {
            var geom = evt.target;
            const geometry = sketch.getGeometry()
            tooltipCoord = geom.getLastCoordinate();
            corrdinates = geometry.getCoordinates()
            point = corrdinates.slice(0, 2).map(m => transformNowToLonlat(m))
            // 角度
            const drawData = CalculationAngle(point)
            // 距离
            util = formatLengthForUtil(geom);
            msg = `ERBL: ${util.output}  ${drawData}°`;
            measureTooltipElement.innerHTML = msg
            measureTooltip.setPosition(tooltipCoord);
            if (corrdinates.length >= 3) {
              setTimeout(() => {
                lineDraw.finishDrawing()
              }, 0);
            }
          });
        }, this);

      lineDraw.on('drawend',
        function () {
          sketch = null;
          // 移除事件监听
          unByKey(listener);
          map.un('pointermove', pointerMoveHandler);
          // 坐标点local存储
          // let list = getStore({
          //   name: chartConfig.chartDrawName,
          // })
          // const row = {
          //   type: "ERBL",
          //   output: msg,
          //   util: util,
          //   list: point
          // }
          // if (!list) {
          //   list = [row]
          // } else {
          //   list.push(row)
          // }
          // setStore({
          //   name: chartConfig.chartDrawName,
          //   content: list
          // })
          // 移除地图单击事件
          map.removeInteraction(CircleDraw);
          map.removeInteraction(lineDraw);
        }, this);
    }
    function createMeasureTooltip() {
      if (measureTooltipElement) {
        measureTooltipElement.parentNode.removeChild(measureTooltipElement);
      }
      measureTooltipElement = document.createElement('div');
      measureTooltipElement.className = 'draw-tooltip tooltip-measure';
      measureTooltip = new Overlay({
        element: measureTooltipElement,
        offset: [0, -15],
        positioning: 'bottom-center'
      });
      map.addOverlay(measureTooltip);
    }

    addInteraction()
  },
  // 清空绘制
  handleClearDraw: (layerTmp, map) => {
    if (layerTmp.getSource()) {
      layerTmp.getSource().clear()
    }
    map.removeLayer(layerTmp)
    var Drawom = document.getElementsByClassName("draw-tooltip");
    for (let i = Drawom.length - 1; i >= 0; --i) {
      if (Drawom[i] != null) Drawom[i].parentNode.removeChild(Drawom[i]);
    }
    removeStore({
      name: chartConfig.chartDrawName,
    });
  },
  // 报警区域
  drawAlarm: (map, row) => {
    return new Promise(resolve => {
      var sketch;
      var helpTooltipElement;
      var helpTooltip;
      var continuePolygonMsg = '双击结束绘制';
      var continueLineMsg = '双击结束绘制';
      createHelpTooltip();
      var pointerMoveHandler = function (evt) {
        if (evt.dragging) {
          return;
        }
        /** @type {string} */
        var helpMsg = '请点击开始绘制';

        if (sketch) {
          var geom = (sketch.getGeometry());
          if (geom instanceof Polygon) {
            helpMsg = continuePolygonMsg;
          } else if (geom instanceof LineString) {
            helpMsg = continueLineMsg;
          }
        }
        helpTooltipElement.innerHTML = helpMsg;
        helpTooltip.setPosition(evt.coordinate);
        helpTooltipElement.classList.remove('hidden');
      };

      // 添加鼠标事件
      map.on('pointermove', pointerMoveHandler);
      map.getViewport().addEventListener('mouseout', function () {
        helpTooltipElement.classList.add('hidden');
      });

      var draw;
      var source;
      let layerTmp = map.getLayers().getArray().find(m => m.get("name") === "ALARM")
      if (!layerTmp) {
        layerTmp = new VectorLayer({
          source: new VectorSource({
            features: [],
          }),
          zIndex: LayerZIndex.alarm,
          name: "ALARM",
        });
        map.addLayer(layerTmp)
      }
      source = layerTmp.getSource();

      // 将帮助提示语添加到图层中
      function createHelpTooltip() {
        if (helpTooltipElement) {
          helpTooltipElement.parentNode.removeChild(helpTooltipElement);
        }
        helpTooltipElement = document.createElement('div');
        helpTooltipElement.className = 'tooltip hidden';
        helpTooltip = new Overlay({
          element: helpTooltipElement,
          offset: [15, 0],
          positioning: 'center-left'
        });
        map.addOverlay(helpTooltip);
      }

      // 图形样式
      draw = new Draw({
        source: source,
        type: "Polygon",
        style: measureStyle
      })
      map.addInteraction(draw);

      var listener;
      draw.on('drawstart',
        function (evt) {
          sketch = evt.feature;
        }, this);

      draw.on('drawend',
        function (e) {
          sketch = null;
          // 移除事件监听
          unByKey(listener);
          map.un('pointermove', pointerMoveHandler);
          const geometry = e.feature.getGeometry()
          let corrdinates = geometry.getCoordinates()
          if (corrdinates.length === 1) {
            corrdinates = corrdinates[0]
          }
          row.list = corrdinates.map(m => transformNowToLonlat(m))
          // 移除地图单击事件
          map.removeInteraction(draw);
          helpTooltipElement.classList.add('hidden');
          // 返回数据
          resolve(row)
        }, this);
    })
  },
  // 复现报警区域
  drawAlarmRegion: (map, data) => {
    var geojsonObject = {
      type: 'FeatureCollection',
      crs: {
        type: 'name',
        properties: {
          name: 'EPSG: 3857'
        }
      },
      features: []
    };
    for (const index in data) {
      let item = data[index]
      item.index = index
      const list = item.pointList.map(m => {
        return transformLonlatToNow([m.lon, m.lat])
      })
      // 将坐标点放入geo中
      geojsonObject.features.push(
        {
          type: 'Feature',
          geometry: {
            type: "Polygon",
            coordinates: [list],
          },
          properties: item
        }
      )
    }
    var source = new VectorSource({
      features: (new GeoJSON()).readFeatures(geojsonObject)
    });
    let layerTmp = map.getLayers().getArray().find(m => m.get("name") === "ALARM")
    if (layerTmp) map.removeLayer(layerTmp)
    layerTmp = new VectorLayer({
      source: source,
      zIndex: LayerZIndex.alarm,
      name: "ALARM",
      style: areaStyleFn
    });
    map.addLayer(layerTmp)
  },
  // 标记 - 执法点
  drawSign: (map) => {
    return new Promise(resolve => {
      var helpTooltipElement;
      var helpTooltip;
      // 创建两个提示框实例
      createHelpTooltip();
      var pointerMoveHandler = function (evt) {
        if (evt.dragging) {
          return;
        }
        var helpMsg = '点击获取坐标';
        helpTooltipElement.innerHTML = helpMsg;
        helpTooltip.setPosition(evt.coordinate);
        helpTooltipElement.classList.remove('hidden');
      };
      var clickHandler = function (evt) {
        if (evt.dragging) {
          return;
        }
        createSignTool(transformNowToLonlat(evt.coordinate))
        map.un('pointermove', pointerMoveHandler);
        map.un('click', clickHandler);
      };

      // 添加鼠标事件
      map.on('pointermove', pointerMoveHandler);
      map.on('click', clickHandler);

      function createSignTool(coordinate) {
        helpTooltipElement.parentNode.removeChild(helpTooltipElement);
        resolve(coordinate)
      }

      function createHelpTooltip() {
        if (helpTooltipElement) {
          helpTooltipElement.parentNode.removeChild(helpTooltipElement);
        }
        helpTooltipElement = document.createElement('div');
        helpTooltipElement.className = 'tooltip hidden';
        helpTooltip = new Overlay({
          element: helpTooltipElement,
          offset: [15, 0],
          positioning: 'center-left'
        });
        map.addOverlay(helpTooltip);
      }
    })
  },
  // 复现标记
  reappearanceSign: (map, data) => {
    var geojsonObject = {
      type: 'FeatureCollection',
      crs: {
        type: 'name',
        properties: {
          name: chartConfig.EPSGCode
        }
      },
      features: []
    };
    const colorMap = {
      1: {
        color: "#dd3232",
        icon: "sign_place.png"
      },
      2: {
        color: "#0b70f7",
        icon: "sign_stop.png"
      },
      3: {
        color: "#0b70f7",
        icon: "sign_fishing.png"
      },
      4: {
        color: "#0b70f7",
        icon: "sign_law.png"
      },
      5: {
        color: "#0b70f7",
        icon: "sign_stop.png"
      },
      6: {
        color: "#A70DFF",
        icon: "sign_point.png"
      },
    }
    for (let item of data) {
      geojsonObject.features.push(
        {
          type: 'Feature',
          geometry: {
            type: "Point",
            coordinates: transformLonlatToNow([item.lon, item.lat])
          },
          properties: item
        }
      )
    }
    const setMapStyle = (feature) => {
      let styleList = []
      const Coordinates = feature.getGeometry().getCoordinates();
      styleList.push(new Style({
        zIndex: LayerZIndex.sign,
        image: new Icon({
          src: `/img/chart/${colorMap[feature.values_.markType].icon}`,
          color: colorMap[feature.values_.markType].color
        }),
        text: new Text({
          text: map.getView().getZoom() >= 12 ? feature.values_.dest : "",
          font: '14px sans-serif',
          fill: new Fill({
            color: "#000066",
          }),
          offsetX: 0,
          offsetY: 15,
        }),
        geometry: new Point(Coordinates)
      }))
      return styleList
    }
    var source = new VectorSource({
      features: (new GeoJSON()).readFeatures(geojsonObject)
    });
    let layerTmp = map.getLayers().getArray().find(m => m.get("name") === "SIGN")
    if (layerTmp) map.removeLayer(layerTmp)
    layerTmp = new VectorLayer({
      source: source,
      zIndex: LayerZIndex.sign,
      name: "SIGN",
      style: setMapStyle
    });
    map.addLayer(layerTmp)

  },
  // 台风绘制
  drawTyphoon: (map, row, fn = () => { }) => {
    var geojsonObject = {
      type: 'FeatureCollection',
      crs: {
        type: 'Typhoon',
      },
      features: []
    };
    // 点绘制
    const drawPointStyle = (row, type) => {
      row.featureType = "typhoon"
      return {
        type: 'Feature',
        geometry: {
          type: "Point",
          coordinates: transformLonlatToNow([parseFloat(row.lon), parseFloat(row.lat)])
        },
        id: `typhoon-Point-${type}-${row.id}`,
        properties: row
      }
    }
    // 线绘制
    const drawLineStyle = (row, type) => {
      let lineList = transformLineForPoint(row.lineList, transformLonlatToNow)
      row.lineType = type
      return {
        type: 'Feature',
        geometry: {
          type: "LineString",
          coordinates: lineList
        },
        id: `typhoon-LineString-${type}-${row.id}`,
        properties: row
      }
    }
    // 获取中间点位
    const getCenterPoint = () => {
      if (row.historyPoint && row.historyPoint.length > 0) {
        return row.historyPoint[row.historyPoint.length - 1]
      } else {
        return row.gfs[0]
      }
    }
    // 绘制旋风动画
    const drawWindStyle = (point) => {
      let time = 0
      window[`typhoon_${row.id}`] = setInterval(() => {
        time -= 10
        feature.setStyle(new Style({
          image: new Icon({
            src: '/img/chart/typhoon.gif',
            rotation: Math.PI / (180 / time)
          }),
          zIndex: LayerZIndex.typhoon
        }))
      }, 100);
      let feature = new Feature({
        geometry: pointLonToXy(point[0], point[1]),
        properties: { type: "wind" }
      });
      feature.setId("gif-1");
      return feature
    }
    // 不同风力强度颜色
    const pointColorList = {
      7: "#076DEB",
      8: "#FEF301",
      9: "#FEF301",
      10: "#FC8F2B",
      11: "#FC8F2B",
      12: "#FE0405"
    }
    // 台风样式 - 点、线、圈
    const typhoonStyleFn = (feature) => {
      const strengthColors = {
        7: {
          fill: "rgba(216, 210, 67, 0.2)",
          stroke: "rgba(216, 210, 67, 1)"
        },
        10: {
          fill: "rgba(252,143,43, 0.2)",
          stroke: "rgba(252,143,43, 1)"
        },
        12: {
          fill: "rgba(221, 0, 0, 0.2)",
          stroke: "rgba(221, 0, 0, 1)"
        }
      }
      const detail = feature.values_
      const coordinatesType = feature.getGeometry().getType();
      const Coordinates = feature.getGeometry().getCoordinates();
      if (coordinatesType === "Point") {
        const strong = findStrength(detail.maxSP)
        return new Style({
          zIndex: 10,
          image: new CircleStyle({
            radius: 4,
            fill: new Fill({
              color: pointColorList[strong] || (strong < 7 ? pointColorList[7] : pointColorList[12]),
            }),
          }),
          geometry: new Point(Coordinates),
        })
      } else if (coordinatesType === "LineString") {
        const strong = findStrength(detail.maxSP)
        return new Style({
          zIndex: 10,
          stroke: new Stroke({
            color: pointColorList[strong] || (strong < 7 ? pointColorList[7] : pointColorList[12]),
            width: 2,
            lineDash: detail.lineType === 1 ? [5, 8] : undefined,
          }),
        })
      } else {
        return new Style({
          fill: new Fill({
            color: strengthColors[detail.level].fill
          }),
          stroke: new Stroke({
            color: strengthColors[detail.level].stroke,
            width: 2
          }),
        });
      }
    }
    // 绘制风圈
    const drawWindCircle = (point) => {
      let featureList = []
      const getPolygonFeature = (point, level) => {
        var wktformat = new WKT();
        const lonlat = transformLonlatToNow([point.lon, point.lat])
        var wkt = "POLYGON((";
        var wkt0 = "", _interval = 6;
        for (var i = 0; i < 360 / _interval; i++) {
          var _r = 0;
          var _ang = i * _interval;
          if (_ang > 0 && _ang <= 90) {
            _r = getRadius((point[`r${level}Ne`] > 0 ? point[`r${level}Ne`] : 0) * 1000, map);
          }
          else if (_ang > 90 && _ang <= 180) {
            _r = getRadius((point[`r${level}Nw`] > 0 ? point[`r${level}Nw`] : 0) * 1000, map);
          }
          else if (_ang > 180 && _ang <= 270) {
            _r = getRadius((point[`r${level}Sw`] > 0 ? point[`r${level}Sw`] : 0) * 1000, map);
          }
          else {
            _r = getRadius((point[`r${level}Se`] > 0 ? point[`r${level}Se`] : 0) * 1000, map);
          }

          var x = lonlat[0] + _r * Math.cos(_ang * 3.14 / 180);
          var y = lonlat[1] + _r * Math.sin(_ang * 3.14 / 180);

          wkt = wkt + "" + x + " " + y + ", ";
          if (i === 0) {
            wkt0 = "" + x + " " + y + "";
          }
        }
        wkt = wkt + wkt0 + "))";
        let feature = wktformat.readFeature(wkt)
        feature.setProperties({ level })
        return feature
      }
      let level = [7, 10, 12]
      const strength = findStrength(centerPoint.maxSP)
      for (let num of level) {
        if (strength > num) {
          featureList.push(getPolygonFeature(point, num))
        }
      }
      return featureList
    }
    // 创建图层
    const createLayer = (geojsonObject, list) => {
      let layerTmp = map
        .getLayers()
        .getArray()
        .find(m => m.get("name") === `typhoon_${row.id}`);
      if (layerTmp) {
        map.removeLayer(layerTmp)
      }
      let source = new VectorSource({
        features: (new GeoJSON()).readFeatures(geojsonObject)
      })
      layerTmp = new VectorLayer({
        source: source,
        zIndex: LayerZIndex.weather,
        name: `typhoon_${row.id}`,
        style: typhoonStyleFn
      });
      for (let feature of list) {
        source.addFeature(feature)
      }
      map.addLayer(layerTmp)
    }
    // 遍历历史点，依次插入点和线
    for (let index in row.historyPoint) {
      let item = row.historyPoint[index]
      item.name = row.stormName || row.id
      geojsonObject.features.push(drawPointStyle(item, 0))
      if (index != row.historyPoint.length - 1) {
        let nextPoint = row.historyPoint[parseInt(index) + 1]
        item.lineList = [[item.lon, item.lat], [nextPoint.lon, nextPoint.lat]]
        geojsonObject.features.push(drawLineStyle(item, 0))
      }
    }
    // 定义预测点，默认获取第一个预测点
    if (row.forecastSets.length > 0 && row.forecastSets[0].forecastPoints.length > 0) {
      row.gfs = row.forecastSets[0].forecastPoints
    } else {
      row.gfs = []
    }
    // 判断历史点和预测点之间是否需要连接线
    if (row.historyPoint && row.historyPoint.length > 0 && row.gfs.length > 0) {
      let item = row.historyPoint[row.historyPoint.length - 1]
      item.name = row.stormName || row.id
      let nextPoint = row.gfs[0]
      item.lineList = [[item.lon, item.lat], [nextPoint.lon, nextPoint.lat]]
      geojsonObject.features.push(drawLineStyle(item, 1))
    }
    // 遍历预测点
    for (let index in row.gfs) {
      let item = row.gfs[index]
      item.name = row.stormName || row.id
      geojsonObject.features.push(drawPointStyle(item, 1))
      // geojsonObject.features.push(drawLineStyle(item, 1))
      if (index != row.gfs.length - 1) {
        let nextPoint = row.gfs[parseInt(index) + 1]
        item.lineList = [[item.lon, item.lat], [nextPoint.lon, nextPoint.lat]]
        geojsonObject.features.push(drawLineStyle(item, 1))
      }
    }
    // 中间点
    let centerPoint = getCenterPoint()
    // 绘制旋风动画
    const point = [centerPoint.lon, centerPoint.lat]
    // 创建图层
    createLayer(geojsonObject, [drawWindStyle(point), ...drawWindCircle(centerPoint)])
    // 中心点跳转到台风所在位置
    var view = map.getView();
    // 设置地图等级
    view.animate({
      center: transformLonlatToNow([centerPoint.lon, centerPoint.lat]),
      duration: 2000,
      zoom: 6
    });
  },
  closeAllTyphoon: (list, map) => {
    for (let item of list) {
      let layerTmp = map
        .getLayers()
        .getArray()
        .find(m => m.get("name") === `typhoon_${item}`);
      if (layerTmp) {
        clearInterval(window[`typhoon_${item}`])
        map.removeLayer(layerTmp)
      }
    }
  },
  closeTyphoon: (row, map) => {
    let layerTmp = map
      .getLayers()
      .getArray()
      .find(m => m.get("name") === `typhoon_${row.id}`);
    if (layerTmp) {
      clearInterval(window[`typhoon_${row.id}`])
      map.removeLayer(layerTmp)
    }
  },
  closeGif: (map, time, id) => {
    let layerTmp = map
      .getLayers()
      .getArray()
      .find(m => m.get("name") === "TYPHOONGIF");
    if (layerTmp) {
      let gifSource = layerTmp.getSource()
      let gifFeature = gifSource.getFeatureById(id);
      gifSource.removeFeature(gifFeature)
    }
    clearInterval(time)
  },
  // 复现MOB
  drawMob: (map, data) => {
    var styles = []
    var source = new VectorSource({
      features: []
    });

    const setFeature = (row) => {
      let shipFeature = new Feature({
        geometry: pointLonToXy(row.longitude, row.lat),
        sty: 'mob',
        detail: row
      });
      shipFeature.setStyle(new Style({
        image: new Icon({
          src: "/img/chart/mob.png",
        }),
      }))
      return shipFeature
    }
    for (let item of data) {
      source.addFeature(setFeature(item));
    }
    let layerTmp = map.getLayers().getArray().find(m => m.get("name") === "MOB")
    if (layerTmp) map.removeLayer(layerTmp)
    layerTmp = new VectorLayer({
      source: source,
      zIndex: LayerZIndex.mob,
      name: "MOB",
      style: styles
    });
    map.addLayer(layerTmp)
  },
  /**
   * 显示共享信息
   *  prim
      0、无
      1、点
      2、先
      3、面
      4、圆
      5、椭圆
   * @param {*} map
   * @param {*} list
   */
  drawShareInfo: (map, list) => {
    var geojsonObject = {
      type: 'FeatureCollection',
      crs: {
        type: 'name',
        properties: {
          name: chartConfig.EPSGCode
        }
      },
      features: []
    };
    for (let item of list) {
      let geometryObj = {}
      if (item.prim === "1") {
        const pointList = item.lngAndLat[0]
        geometryObj = {
          type: "Point",
          coordinates: transformLonlatToNow([pointList.longitude, pointList.latitude]),
        }
      } else if (item.prim === "2") {
        geometryObj = {
          type: "LineString",
          coordinates: item.lngAndLat.map(m => transformLonlatToNow([m.longitude, m.latitude]))
        }
      } else if (item.prim === "3") {
        geometryObj = {
          type: "Polygon",
          coordinates: [item.lngAndLat.map(m => transformLonlatToNow([m.longitude, m.latitude]))]
        }
      } else {
        continue
      }
      geojsonObject.features.push({
        type: 'Feature',
        geometry: geometryObj,
        properties: item
      })
    }
    var source = new VectorSource({
      features: (new GeoJSON()).readFeatures(geojsonObject)
    });
    let layerTmp = map.getLayers().getArray().find(m => m.get("name") === "SHARE")
    if (!layerTmp) {
      layerTmp = new VectorLayer({
        source: source,
        zIndex: LayerZIndex.shareInfo,
        name: "SHARE",
        style: shareStyleFn
      });
      map.addLayer(layerTmp)
    }
  },
  // 航海通告
  drawNoticeInfo: (map, list) => {
    var geojsonObject = {
      type: 'FeatureCollection',
      crs: {
        type: 'name',
        properties: {
          name: chartConfig.EPSGCode
        }
      },
      features: []
    };
    for (let item of list) {
      let geometryObj = {}
      if (item.prim === "1") {
        const pointList = item.lngAndLat[0]
        geometryObj = {
          type: "Point",
          coordinates: transformLonlatToNow([pointList.longitude, pointList.latitude]),
        }
      } else if (item.prim === "2") {
        geometryObj = {
          type: "LineString",
          coordinates: item.lngAndLat.map(m => transformLonlatToNow([m.longitude, m.latitude]))
        }
      } else if (item.prim === "3") {
        geometryObj = {
          type: "Polygon",
          coordinates: [item.lngAndLat.map(m => transformLonlatToNow([m.longitude, m.latitude]))]
        }
      } else {
        continue
      }
      geojsonObject.features.push({
        type: 'Feature',
        geometry: geometryObj,
        properties: item
      })
    }
    var source = new VectorSource({
      features: (new GeoJSON()).readFeatures(geojsonObject)
    });
    let layerTmp = map.getLayers().getArray().find(m => m.get("name") === "NOTICE")
    if (!layerTmp) {
      layerTmp = new VectorLayer({
        source: source,
        zIndex: LayerZIndex.notice,
        name: "NOTICE",
        style: noticeStyleFn
      });
      map.addLayer(layerTmp)
    }
  },
  /**
   * 绘制闪烁点（仅可用于无延展海图）
   * @param {*} map
   * @param {*} list [lon, lat]
   */
  drawAlarmPoint: (map, list, row) => {
    let dom = document.createElement('div');
    dom.className = 'alarm-point';
    // dom.setAttribute('id', 'alarm_point_id');
    const PointId = "alarm_point_detail_" + row.caseId
    const coordinate = transformLonlatToNow(list)
    dom.addEventListener("mouseenter", () => {
      AlarmInfoTips(row, coordinate, map, PointId, "alarm-point-detail")
    })
    dom.addEventListener("mouseleave", () => {
      removeDomById(PointId)
    })
    var point_overlay = new Overlay({
      element: dom,
      positioning: 'center-center',
      id: "alarm"
    });
    map.addOverlay(point_overlay);
    point_overlay.setPosition(coordinate);
  },
  // 绘制保护区
  drawAquatics: (map, data) => {
    var geojsonObject = {
      type: 'FeatureCollection',
      crs: {
        type: 'name',
        properties: {
          name: 'EPSG: 3857'
        }
      },
      features: []
    };
    // 遍历插值
    for (const index in data) {
      let item = data[index]
      item.index = index
      const list = item.pointList.map(m => {
        return transformLonlatToNow([m.lon, m.lat])
      })
      // 将坐标点放入geo中
      geojsonObject.features.push(
        {
          type: 'Feature',
          geometry: {
            type: "Polygon",
            coordinates: [list],
          },
          properties: item
        }
      )
    }
    // 图形样式
    const setStyleFn = (feature) => {
      let list = []
      list.push(
        new Style({
          fill: new Fill({
            color: "rgba(255, 80, 80, 0.2)",
          }),
          stroke: new Stroke({
            color: "rgba(255, 80, 80, 1)",
            width: 1.5
          }),
        })
      )
      const lonAndLat = feature.values_.pointList.map(m => transformLonlatToNow([m.lon, m.lat]))
      const centerPoint = getCenterPoint(lonAndLat)
      list.push(
        new Style({
          zIndex: 10,
          text: new Text({
            text: map.getView().getZoom() > 12 ? feature.values_.areaName : "",
            font: '30px sans-serif',
            fill: new Fill({
              color: "rgba(0, 0, 0, 0.5)",
            }),
          }),
          geometry: new Point(centerPoint),
        })
      );
      return list
    }
    // 添加图层
    var source = new VectorSource({
      features: (new GeoJSON()).readFeatures(geojsonObject)
    });
    let layerTmp = map.getLayers().getArray().find(m => m.get("name") === "Aquatic")
    if (layerTmp) map.removeLayer(layerTmp)
    layerTmp = new VectorLayer({
      source: source,
      zIndex: LayerZIndex.aquatic,
      name: "Aquatic",
      style: setStyleFn
    });
    map.addLayer(layerTmp)
  },
  // 绘制保护区
  drawAquatic: (map, data) => {
    var geojsonObject = {
      type: 'FeatureCollection',
      crs: {
        type: 'name',
        properties: {
          name: 'EPSG: 3857'
        }
      },
      features: []
    };
    // 遍历插值
    for (const index in data) {
      let item = data[index]
      item.index = index
      const list = item.pointList.map(m => {
        return transformLonlatToNow([m.lon, m.lat])
      })
      // 将坐标点放入geo中
      geojsonObject.features.push(
        {
          type: 'Feature',
          geometry: {
            type: "Polygon",
            coordinates: [list],
          },
          properties: item
        }
      )
    }
    // 图形样式
    const setStyleFn = (feature) => {
      let list = []
      list.push(
        new Style({
          fill: new Fill({
            color: "rgba(255, 80, 80, 0.2)",
          }),
          stroke: new Stroke({
            color: "rgba(255, 80, 80, 1)",
            width: 1.5
          }),
          image: new Icon({
            src: `/img/chart/11.jpg`,
          }),
        })
      )
      const lonAndLat = feature.values_.pointList.map(m => transformLonlatToNow([m.lon, m.lat]))
      const centerPoint = getCenterPoint(lonAndLat)
      list.push(
        new Style({
          zIndex: 10,
          text: new Text({
            text: map.getView().getZoom() > 12 ? feature.values_.areaName : "",
            font: '30px sans-serif',
            fill: new Fill({
              color: "rgba(0, 0, 0, 0.5)",
            }),
          }),
          geometry: new Point(centerPoint),
        })
      );
      return list
    }
    // 添加图层
    var source = new VectorSource({
      features: (new GeoJSON()).readFeatures(geojsonObject)
    });
    let layerTmp = map.getLayers().getArray().find(m => m.get("name") === "Aquatic")
    if (layerTmp) map.removeLayer(layerTmp)
    layerTmp = new VectorLayer({
      source: source,
      zIndex: LayerZIndex.aquatic,
      name: "Aquatic",
      style: setStyleFn
    });
    map.addLayer(layerTmp)
  },
  // 绘制雷达
  drawRadar: (map, data, options) => {
    var geojsonObject = {
      type: 'FeatureCollection',
      crs: {
        type: 'name',
        properties: {
          name: chartConfig.EPSGCode
        }
      },
      features: []
    };
    for (let item of data) {
      item.drawType = "radar"
      // 圆心
      geojsonObject.features.push(
        {
          type: 'Feature',
          geometry: {
            type: "Point",
            coordinates: transformLonlatToNow([item.lon, item.lat]),
            id: "ss"
          },
          properties: item
        }
      )
    }
    const setPointStyle = (feature) => {
      const Coordinates = feature.getGeometry().getCoordinates();
      return new Style({
        zIndex: LayerZIndex.sign,
        image: new Icon({
          src: `/img/chart/radar.png`,
          // color: colorMap[feature.values_.markType].color
        }),
        text: new Text({
          // text: map.getView().getZoom() >= 12 ? feature.values_.name : "",
          font: '14px sans-serif',
          fill: new Fill({
            color: "#000066",
          }),
          offsetX: 0,
          offsetY: 25,
        }),
        geometry: new Point(Coordinates)
      })
    }
    const setCircleStyle = (feature) => {
      const type = feature.values_.type;
      if (type === "min") {
        return new Style({
          stroke: new Stroke({ // 边缘颜色
            color: "rgba(242, 253, 2)",
            width: 2.5
          }),
        })
      } else {
        return new Style({
          // fill: new Fill({ // 填充颜色
          //   color: "rgba(200, 20, 20, 0.15)"
          // }),
          stroke: new Stroke({ // 边缘颜色
            color: "rgba(245, 6, 249)",
            width: 2.5
          }),
        })
      }
    }
    const setMapStyle = (feature) => {
      const coordinatesType = feature.getGeometry().getType();
      let styleList = []
      if (coordinatesType === "Point") {
        styleList.push(setPointStyle(feature))
      } else {
        styleList.push(setCircleStyle(feature))
      }
      return styleList
    }
    var source = new VectorSource({
      features: (new GeoJSON()).readFeatures(geojsonObject)
    });
    // 显示范围
    if (options.rangeShow === 1) {
      for (let item of data) {
        // 雷达范围
        var minCircle = new Feature({
          geometry: new Circle(transformLonlatToNow([item.lon, item.lat]), parseFloat(item.minLength) * nMile),
          type: "min",
        })
        var maxCircle = new Feature({
          geometry: new Circle(transformLonlatToNow([item.lon, item.lat]), parseFloat(item.maxLength) * nMile),
          type: "max",
        })
        source.addFeature(minCircle);
        source.addFeature(maxCircle);
      }
    }
    let layerTmp = map.getLayers().getArray().find(m => m.get("name") === "RADAR")
    if (layerTmp) map.removeLayer(layerTmp)
    layerTmp = new VectorLayer({
      source: source,
      zIndex: LayerZIndex.radar,
      name: "RADAR",
      style: setMapStyle
    });
    map.addLayer(layerTmp)
  },
  // 雷达贴图
  drawRadarImage: (map, data) => {
    var geojsonObject = {
      type: 'FeatureCollection',
      crs: {
        type: 'name',
        properties: {
          name: chartConfig.EPSGCode
        }
      },
      features: []
    };
    for (let item of data) {
      // 圆心
      geojsonObject.features.push(
        {
          type: 'Feature',
          geometry: {
            type: "Point",
            coordinates: transformLonlatToNow([item.lon, item.lat])
          },
          properties: item
        }
      )
    }
    const setPointStyle = (feature) => {
      const Coordinates = feature.getGeometry().getCoordinates();
      return new Style({
        zIndex: LayerZIndex.sign,
        image: new Icon({
          src: `/img/chart/11.jpg`,
          size: [15, 15],
          // imgSize: 20,
          // resolution: 1,
          // color: colorMap[feature.values_.markType].color
        }),
        geometry: new Point(Coordinates)
      })
    }
    const setMapStyle = (feature) => {
      let styleList = []
      styleList.push(setPointStyle(feature))
      return styleList
    }
    var source = new VectorSource({
      features: (new GeoJSON()).readFeatures(geojsonObject)
    });
    let layerTmp = map.getLayers().getArray().find(m => m.get("name") === "RADAR")
    if (layerTmp) map.removeLayer(layerTmp)
    layerTmp = new VectorLayer({
      source: source,
      zIndex: LayerZIndex.radar,
      name: "RADAR",
      style: setMapStyle
    });
    map.addLayer(layerTmp)
  },
}
